package com.example.gobang2.game;

import com.example.gobang2.Gobang2Application;
import com.example.gobang2.mapper.UserMapper;
import com.example.gobang2.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.Stack;
import java.util.UUID;
@Data
public class Room {
    private String roomId;
    private User user1;
    private User user2;
    private int whiteUserId = 0;
    private static final int MAX_ROW = 15;
    private static final int MAX_COL = 15;
    private int[][] chessBoard = new int[MAX_ROW][MAX_COL];
    private ObjectMapper objectMapper = new ObjectMapper();
    private OnlineUserManager onlineUserManager;
    private RoomManager roomManager;
    private UserMapper  userMapper;
    private Stack<String> chessStack = new Stack<>();

    public Room(){
        roomId = UUID.randomUUID()+"";
        onlineUserManager = Gobang2Application.ac.getBean(OnlineUserManager.class);
        roomManager = Gobang2Application.ac.getBean(RoomManager.class);
        userMapper = Gobang2Application.ac.getBean(UserMapper.class);
    }


    public void putChess(String payload) throws IOException {
        GameRequest request = objectMapper.readValue(payload,GameRequest.class);
        GameResponse response = new GameResponse();

        int chess = request.getUserId() == user1.getUserId()?1 : 2;
        int row = request.getRow();
        int col = request.getCol();

        if(chessBoard[row][col]!=0){
            System.out.println("[Room] 落子位置已经有棋子了");
            return;
        }

        chessBoard[row][col] = chess;
        int winner = checkWinner(chess,row,col);

        response.setUserId(request.getUserId());
        response.setRow(row);
        response.setCol(col);
        response.setWinner(winner);
        response.setMessage("putChess");

        WebSocketSession session1 = onlineUserManager.getSessionFromGameRoom(user1.getUserId());
        WebSocketSession session2 = onlineUserManager.getSessionFromGameRoom(user2.getUserId());

        if(session1==null){
            response.setWinner(user2.getUserId());
            System.out.println("[Room] 玩家1掉线，默认为玩家2获胜！");
        }

        if(session2==null){
            response.setWinner(user1.getUserId());
            System.out.println("[Room] 玩家2掉线，默认为玩家1获胜！");
        }

        if(session1!=null){
            session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
        if(session2!=null){
            session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

        if(winner!=0){
            userMapper.userWin(response.getWinner()== user1.getUserId()?user1:user2);
            userMapper.userLose(response.getWinner()==user1.getUserId()?user2:user1);
            roomManager.removeRoom(user1.getUserId(),user2.getUserId(),roomId);
            System.out.println("[Room] 游戏结束，房间："+roomId+",已经销毁！获胜方为："+winner);
        }
        chessStack.push(objectMapper.writeValueAsString(response));
    }

    //悔棋实现
    public boolean backMove() throws JsonProcessingException {
        if (!chessStack.isEmpty()) {
            String lastMove = chessStack.pop();
            System.out.println("lastMove信息:"+lastMove);
            GameRequest request = objectMapper.readValue(lastMove, GameRequest.class);
            int row = request.getRow();
            int col = request.getCol();
            System.out.println("行："+row+"列："+col);
            chessBoard[row][col] = 0;
            // 清空棋盘对应位置
            return true;
        }
        return false;
    }

    private int checkWinner(int chess, int row, int col) {
        boolean done = false;
        for (int c = col - 4; c <= col; c++) {
            if (c < 0 || c >= 15) {
                continue;
            }
            if (chessBoard[row][c] == chess
                    && chessBoard[row][c + 1] == chess
                    && chessBoard[row][c + 2] == chess
                    && chessBoard[row][c + 3] == chess
                    && chessBoard[row][c + 4] == chess) {
                done = true;
            }
        }
        for (int r = row - 4; r <= row; r++) {
            if (r < 0 || r >= MAX_ROW) {
                continue;
            }
            if (chessBoard[r][col] == chess
                    && chessBoard[r + 1][col] == chess
                    && chessBoard[r + 2][col] == chess
                    && chessBoard[r + 3][col] == chess
                    && chessBoard[r + 4][col] == chess) {
                done = true;
            }
        }
        for (int r = row - 4, c = col - 4; r <= row && c <= col; r++, c++) {
            if (r < 0 || r >= MAX_ROW || c < 0 || c >= MAX_COL) {
                continue;
            }
            if (chessBoard[r][c] == chess
                    && chessBoard[r + 1][c + 1] == chess
                    && chessBoard[r + 2][c + 2] == chess
                    && chessBoard[r + 3][c + 3] == chess
                    && chessBoard[r + 4][c + 4] == chess) {
                done = true;
            }
        }
        for (int r = row - 4, c = col + 4; r <= row && c >= col; r++, c--) {
            if (r < 0 || r >= MAX_ROW || c < 0 || c >= MAX_COL) {
                continue;
            }
            if (chessBoard[r][c] == chess
                    && chessBoard[r + 1][c - 1] == chess
                    && chessBoard[r + 2][c - 2] == chess
                    && chessBoard[r + 3][c - 3] == chess
                    && chessBoard[r + 4][c - 4] == chess) {
                done = true;
            }
        }
        if (!done) {
            return 0;
        }
        return chess == 1 ? user1.getUserId() : user2.getUserId();
    }
}
